<template>
  <div class="chart-container" ref="chartRef"></div>
</template>

<script setup>
import { ref, onMounted, onUnmounted, watchEffect } from "vue";
import * as echarts from "echarts";

// 1. 基础引用与固定配置
const chartRef = ref(null);
let myChart = null;
const weekdays = ["周一", "周二", "周三", "周四", "周五"]; // 固定5天（列）
const crossDayRange = "8月10日 12:00 - 8月12日 12:00";
const crossDayTotalHours = 48; // 每日总和固定为48小时
const statusColors = { 通行: "#4CAF50", 不通行: "#F44336" };

// 2. 配置最大系列数（根据业务需求设定）
const MAX_SERIES_COUNT = 5;

// 3. 数据处理
// 3.1 接收后台返回的系列数据（示例：后台只返回2个系列）
const backendData = ref([
  [48, 0, 0, 0, 0], // 系列1
  [10, 10, 10, 18, 0], // 系列2
]);

// 3.2 处理后的数据（补全系列数后）
const rawData = ref([]);
// 3.3 状态数据
const statusData = ref([]);

/**
 * 补全系列数量至最大系列数
 * 后台返回n个系列时，不足则补全为0的系列
 */
const completeSeriesData = () => {
  // 1. 确保每个系列都有5个数据（与周一至周五对应）
  const formattedData = backendData.value.map((series) => {
    const filledSeries = [...series];
    // 补全列数据至5个
    while (filledSeries.length < weekdays.length) {
      filledSeries.push(0);
    }
    // 超过5个则截断
    return filledSeries.slice(0, weekdays.length);
  });

  // 2. 补全系列数量至最大系列数
  const completedData = [...formattedData];
  while (completedData.length < MAX_SERIES_COUNT) {
    // 补全的系列初始值都为0
    completedData.push(Array(weekdays.length).fill(0));
  }

  // 3. 存储补全后的数据
  rawData.value = completedData;
};

/**
 * 确保每日（列）总和为48小时
 * 只调整最后一个系列的数据，避免修改原始数据
 */
const ensureDailyTotal = () => {
  // 遍历每一天（列）
  weekdays.forEach((_, dayIndex) => {
    // 计算除最后一个系列外的总和
    let sum = 0;
    for (let i = 0; i < rawData.value.length - 1; i++) {
      sum += rawData.value[i][dayIndex];
    }

    // 计算最后一个系列需要的值
    const lastSeriesValue = crossDayTotalHours - sum;
    // 设置最后一个系列的值，确保总和为48
    rawData.value[rawData.value.length - 1][dayIndex] = lastSeriesValue;
  });
};

/**
 * 生成状态数据
 */
const generateStatusData = () => {
  statusData.value = rawData.value.map((series, seriesIndex) => {
    return series.map((value) => {
      // 0值不显示状态
      if (value === 0) return "";

      // 这里可以根据实际业务规则设置状态
      // 示例规则：后台返回的系列按值大小，补全的系列默认"通行"
      if (seriesIndex < backendData.value.length) {
        return value > 10 ? "通行" : "不通行";
      } else {
        return "通行";
      }
    });
  });
};

/**
 * 构建图表系列配置
 */
const buildSeries = () => {
  return rawData.value.map((series, seriesIndex) => ({
    name: `系列${seriesIndex + 1}`,
    type: "bar",
    stack: "total",
    barWidth: "60%",
    label: {
      show: true,
      position: "inside",
      color: "#fff",
      fontSize: 10,
      formatter: (params) => {
        const hours = rawData.value[seriesIndex][params.dataIndex];
        const percentage = Math.round((hours / crossDayTotalHours) * 100);
        return `${
          statusData.value[seriesIndex][params.dataIndex]
        }\n${hours}h(${percentage}%)`;
      },
    },
    data: series.map((value, dataIndex) => ({
      value,
      itemStyle: {
        color: statusColors[statusData.value[seriesIndex][dataIndex]] || "#ccc",
      },
    })),
    emphasis: { focus: "series" },
  }));
};

/**
 * 构建图表配置项
 */
const buildChartOption = () => {
  return {
    grid: {
      left: "20%",
      right: "8%",
      top: "18%",
      bottom: "15%",
      containLabel: true,
    },
    title: {
      text: `时间范围：${crossDayRange}（共${crossDayTotalHours}小时/天）`,
      left: "center",
      top: 0,
      textStyle: { fontSize: 14, color: "#333", fontWeight: "normal" },
    },
    legend: {
      data: [
        { name: "通行", icon: "rect", itemStyle: { color: statusColors.通行 } },
        {
          name: "不通行",
          icon: "rect",
          itemStyle: { color: statusColors.不通行 },
        },
      ],
      top: 30,
      left: "center",
      selectedMode: false,
      textStyle: { fontSize: 12, color: "#666" },
      itemWidth: 10,
      itemHeight: 10,
    },
    tooltip: {
      trigger: "axis",
      axisPointer: { type: "shadow" },
      backgroundColor: "rgba(255,255,255,0.95)",
      borderColor: "#eee",
      borderWidth: 1,
      padding: 12,
      textStyle: { color: "#333", fontSize: 12 },
      formatter: (params) => {
        const day = weekdays[params[0].dataIndex];
        let content = `
          <div style="font-weight:600;margin-bottom:6px;">${day}</div>
          <div style="margin-bottom:4px;color:#666;">时间范围：${crossDayRange}</div>
          <div style="margin-bottom:4px;color:#666;">当日总时长：${crossDayTotalHours}小时</div>
        `;
        const sortedParams = [...params].sort((a, b) => b.value - a.value);
        sortedParams.forEach((item) => {
          const seriesIndex = item.seriesIndex;
          const dataIndex = item.dataIndex;
          const status = statusData.value[seriesIndex][dataIndex];
          const percentage = Math.round(
            (item.value / crossDayTotalHours) * 100
          );
          content += `
            <div style="margin-bottom:2px;">
              <span style="display:inline-block;width:10px;height:10px;background:${
                item.color
              };margin-right:6px;"></span>
              ${status || "无状态"}（${item.seriesName}）：${
            item.value
          }小时（${percentage}%）
            </div>
          `;
        });
        return content;
      },
    },
    xAxis: {
      type: "category",
      data: weekdays,
      axisLabel: { fontSize: 14, color: "#333", interval: 0 },
      axisLine: { lineStyle: { color: "#eee" } },
      name: "星期",
      nameTextStyle: { fontSize: 13, color: "#666", padding: [10, 0, 0, 0] },
      nameLocation: "middle",
      nameGap: 30,
    },
    yAxis: {
      type: "value",
      min: 0,
      max: crossDayTotalHours,
      interval: 12,
      axisLabel: {
        formatter: (value) => {
          const startDate = new Date("2023-08-10T12:00:00");
          const currentDate = new Date(startDate.getTime() + value * 3600000);
          const month = String(currentDate.getMonth() + 1).padStart(2, "0");
          const day = String(currentDate.getDate()).padStart(2, "0");
          const hours = String(currentDate.getHours()).padStart(2, "0");
          const minutes = String(currentDate.getMinutes()).padStart(2, "0");
          return `${month}-${day} ${hours}:${minutes}`;
        },
        fontSize: 11,
        color: "#666",
        align: "right",
        padding: [0, 10, 0, 0],
      },
      axisLine: { show: false },
      splitLine: { lineStyle: { color: "#f5f5f5" } },
      name: "时间",
      nameTextStyle: { fontSize: 13, color: "#666" },
      nameLocation: "middle",
      nameGap: 110,
    },
    series: buildSeries(),
    animation: true,
    animationDuration: 1000,
    animationEasing: "cubicOut",
  };
};

/**
 * 初始化图表
 */
const initChart = () => {
  if (!chartRef.value || myChart) return;

  myChart = echarts.init(chartRef.value);

  // 数据处理流程
  completeSeriesData();
  ensureDailyTotal();
  generateStatusData();

  myChart.setOption(buildChartOption());
  window.addEventListener("resize", handleResize);
};

/**
 * 销毁图表
 */
const destroyChart = () => {
  if (myChart) {
    window.removeEventListener("resize", handleResize);
    myChart.dispose();
    myChart = null;
  }
};

/**
 * 处理窗口大小变化
 */
const handleResize = () => {
  myChart?.resize();
};

// 生命周期钩子
onMounted(() => {
  initChart();
});

onUnmounted(() => {
  destroyChart();
});

// 监听后台数据变化，自动更新图表
watchEffect(() => {
  if (backendData.value.length === 0 || !myChart) return;

  completeSeriesData();
  ensureDailyTotal();
  generateStatusData();
  myChart.setOption(buildChartOption());
});
</script>

<style scoped>
.chart-container {
  width: 100%;
  height: 600px;
  margin: 0 auto;
}
</style>
